package config

import (
	"os"
	"sync"

	"gopkg.in/yaml.v3"
)

type Config struct {
	File struct {
		Path           string `yaml:"path"`
		Separator      bool   `yaml:"separator"`
		SeparatorValue string `yaml:"separator_value"`
	}
	API struct {
		BaseURL string `yaml:"base_url"`
		Method  string `yaml:"method"`

		Today struct {
			Key   string `yaml:"key"`
			Value int    `yaml:"value"`
			Cron  string `yaml:"cron"`
		} `yaml:"today"`
		FutureDay struct {
			Key   string `yaml:"key"`
			Value int    `yaml:"value"`
			cron  string `yaml:"cron"`
		} `yaml:"future_day"`
	} `yaml:"api"`

	Request struct {
		Site struct {
			ID      string  `yaml:"id"`
			Name    string  `yaml:"name"`
			Lat     float64 `yaml:"lat"`
			Lng     float64 `yaml:"lng"`
			Terrain struct {
				Elevation float64 `yaml:"elevation"`
				Azimuth   float64 `yaml:"azimuth"`
				Tilt      float64 `yaml:"tilt"`
			} `yaml:"terrain"`
			Horizon string `yaml:"horizon"`
			//固定角度几何形状
			PVGeometry struct {
				Type              string  `yaml:"type"`
				Azimuth           float64 `yaml:"azimuth"`
				Tilt              float64 `yaml:"tilt"`
				AxisTilt          float64 `yaml:"axisTilt"`
				RotationLimitEast float64 `yaml:"rotationLimitEast"`
				RotationLimitWest float64 `yaml:"rotationLimitWest"`
				TiltLimitMin      float64 `yaml:"tiltLimitMin"`
				TiltLimitMax      float64 `yaml:"tiltLimitMax"`
				BackTracking      bool    `yaml:"backTracking"`
			} `yaml:"pv_geometry"`

			PVSystem struct {
				InstalledPower   float64 `yaml:"installed_power"`
				InstallationType string  `yaml:"installation_type"`
				DateStartup      string  `yaml:"date_startup"`
				SelfShading      bool    `yaml:"self_shading"`
				Module           struct {
					Type                     string  `yaml:"type"`
					Degradation              float64 `yaml:"degradation"`
					DegradationFirstYear     float64 `yaml:"degradation_first_year"`
					NominalOperatingCellTemp float64 `yaml:"nominal_operating_cell_temp"`
					PmaxCoeff                float64 `yaml:"pmax_coeff"`
					SurfaceReflectance       float64 `yaml:"surface_reflectance"`
				} `yaml:"module"`
				Inverter struct {
					Efficiency struct {
						Type      string  `yaml:"type"`
						Percent   float64 `yaml:"percent"`
						DataPairs string  `yaml:"data_pairs"`
					} `yaml:"efficiency"`
					LimitationACPower float64 `yaml:"limitation_ac_power"`
				} `yaml:"inverter"`
				Losses struct {
					AC struct {
						Cables      float64 `yaml:"cables"`
						Transformer float64 `yaml:"transformer"`
					} `yaml:"ac"`
					DC struct {
						Cables               float64 `yaml:"cables"`
						Mismatch             float64 `yaml:"mismatch"`
						SnowPollution        float64 `yaml:"snow_pollution"`
						MonthlySnowPollution string  `yaml:"monthly_snow_pollution"`
					} `yaml:"dc"`
				} `yaml:"losses"`
				Topology struct {
					XsiType         string  `yaml:"xsi_type"`
					RelativeSpacing float64 `yaml:"relative_spacing"`
					Type            string  `yaml:"type"`
				} `yaml:"topology"`
			} `yaml:"pv_system"`
		} `yaml:"site"`
		Processing struct {
			Keys           string `yaml:"keys"`
			Summarization  string `yaml:"summarization"`
			TerrainShading bool   `yaml:"terrain_shading"`
			TimeZone       string `yaml:"time_zone"`
			TimestampType  string `yaml:"timestamp_type"`
		} `yaml:"processing"`
	} `yaml:"request"`

	Output struct {
		DailyForecast struct {
			MetadataDir string `yaml:"metadata_dir"`
			DatasetDir  string `yaml:"dataset_dir"`
		} `yaml:"daily_forecast"`
		MidtermForecast struct {
			MetadataDir string `yaml:"metadata_dir"`
			DatasetDir  string `yaml:"dataset_dir"`
		} `yaml:"midterm_forecast"`
		MaxFiles int `yaml:"max_files"`
	} `yaml:"output"`
}

var (
	currentConfig *Config
	configMutex   sync.RWMutex
)

func LoadConfig(path string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	var cfg Config
	if err := yaml.Unmarshal(data, &cfg); err != nil {
		return nil, err
	}

	configMutex.Lock()
	defer configMutex.Unlock()
	currentConfig = &cfg
	return currentConfig, nil
}

func GetConfig() *Config {
	configMutex.RLock()
	defer configMutex.RUnlock()
	return currentConfig
}
